//SPDX-FileCopyrightText: Copyright 2022-2024 深圳市同心圆网络有限公司
//SPDX-License-Identifier: GPL-3.0-only

package upgrade

import (
	"context"
	"math"

	"atomgit.com/openlinksaas-org/api-server/dao"
	"atomgit.com/openlinksaas-org/api-server/dao/fs_dao"
	"atomgit.com/openlinksaas-org/api-server/dao/project_dao"
	"atomgit.com/openlinksaas-org/proto-gen-go.git/fs_api"
	"github.com/google/uuid"
	"go.mongodb.org/mongo-driver/mongo"
)

type UpToVer29 struct{}

func (up *UpToVer29) Exec(ctx context.Context) error {
	prjList, err := project_dao.ProjectInfoDao.ListAll(ctx, 0, math.MaxInt64)
	if err != nil {
		return err
	}
	for _, prj := range prjList {
		err = up.processFs(ctx, prj)
		if err != nil {
			return err
		}
	}
	return dao.VersionDao.Set(ctx, dao.VERSION_KEY_SCHEMA, 29)
}

func (up *UpToVer29) processFs(ctx context.Context, projectItem *project_dao.ProjectInfoDbItem) error {
	if projectItem.TestCaseFsId != "" && projectItem.TestResultFsId != "" {
		return nil
	}

	dbSess, err := dao.StartSession()
	if err != nil {
		return err
	}
	defer dao.EndSession(dbSess)

	_, err = dbSess.WithTransaction(ctx, func(sessCtx mongo.SessionContext) (interface{}, error) {
		if projectItem.TestCaseFsId == "" {
			projectItem.TestCaseFsId = uuid.NewString()
			err2 := fs_dao.FsInfoDao.Insert(sessCtx, &fs_dao.FsInfoDbItem{
				FsId:      projectItem.TestCaseFsId,
				OwnerType: int32(fs_api.FS_OWNER_TYPE_FS_OWNER_TYPE_PROJECT),
				OwnerId:   projectItem.ProjectId,
				Status:    fs_dao.FsStatusDbItem{},
			})
			if err2 != nil {
				return nil, err2
			}
		}
		if projectItem.TestResultFsId == "" {
			projectItem.TestResultFsId = uuid.NewString()
			err2 := fs_dao.FsInfoDao.Insert(sessCtx, &fs_dao.FsInfoDbItem{
				FsId:      projectItem.TestResultFsId,
				OwnerType: int32(fs_api.FS_OWNER_TYPE_FS_OWNER_TYPE_PROJECT),
				OwnerId:   projectItem.ProjectId,
				Status:    fs_dao.FsStatusDbItem{},
			})
			if err2 != nil {
				return nil, err2
			}
		}
		err2 := project_dao.ProjectInfoDao.UpdateProject(sessCtx, projectItem)
		if err2 != nil {
			return nil, err2
		}
		return nil, nil
	})
	return err

}
